//
//  ImageExtension.swift
//  ShiGuangJiaSwift
//
//  Created by 汪志浩 on 2022/7/21.
//

import Foundation
import UIKit

extension UIImage {
    /**创建一张带颜色的图片**/
    class func lzh_imageWithColor(color:UIColor,size:CGSize) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}


let k_s_w = UIScreen.main.bounds.size.width
let k_s_h = UIScreen.main.bounds.size.height


extension UIImage {
    
    
    //获取颜色图片
    static func getColorImage(color:UIColor,size:CGSize) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContext(rect.size)
        let context = UIGraphicsGetCurrentContext()
        context!.setFillColor(color.cgColor)
        context!.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
    
    
    //获取固定大小的图片
    static func getImageWithColor(color:UIColor)->UIImage{
        let size = CGSize(width: 20, height: 20)
        return getColorImage(color: color, size: size)
    }
    
    static func getImageWithColorAndSize(color:UIColor,withSize:CGSize)->UIImage{
        return getColorImage(color: color, size: withSize)
    }
    
    /**压缩质量**/
    func imageCompressForQuality(compressionQuality:CGFloat) -> Data?{
        return self.jpegData(compressionQuality: compressionQuality)
    }
    /**
     *  重设图片大小
     */
    func reSizeImage(reSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions (reSize, false , UIScreen.main.scale)
        draw(in: CGRect(x: 0, y: 0, width: reSize.width, height: reSize.height))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext ();
        return  image!;
    }
    
    /**
     *  等比率缩放
     */
    func scaleImage(scale: CGFloat) -> UIImage  {
        let reSize = CGSize(width: size.width * scale,  height: size.height * scale)
        return reSizeImage(reSize: reSize)
    }
    
    
    /**
     *  获得指定size的图片
     *
     *  image   原始图片
     *  newSize 指定的size
     *
     *  return 调整后的图片
     */
    func resizeImage(image: UIImage, newSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContext(newSize)
        image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
        
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { return image }
        UIGraphicsEndImageContext()
        return newImage
    }
    
    func resizeImage(newSize: CGSize?) -> UIImage {
        let size = newSize ?? CGSize.zero
        UIGraphicsBeginImageContext(size)
        self.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else { return self }
        UIGraphicsEndImageContext()
        return newImage
    }
    
    
    
    /// 颜色转图片
    /// - Parameter size: 大小
    /// - Returns: 图片
    func colorToImage(_ size: CGSize,color:UIColor) -> UIImage {
        
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else {
            return UIImage()
        }
        context.setFillColor(color.cgColor)
        context.fill(rect)
        let resultImage = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
        UIGraphicsEndImageContext()
        return resultImage
    }
    
    
    /**
     2  *  根据image 返回放大或缩小之后的图片
     3  *
     4  *  @param image    原始图片
     5  *  @param multiple 放大倍数 0 ~ 2 之间
     6  *
     7  *  @return 新的image
     8  */
    
    static func createNewImage(image:UIImage,multiple:Double) -> UIImage? {
        var newMultiple = multiple
        if multiple == 0 {
            newMultiple = 1
        } else if (fabs(multiple) > 0 && fabs(multiple) < 1) || (fabs(multiple) > 1 && fabs(multiple) < 2) {
            newMultiple = multiple
        } else {
            newMultiple = 1
        }
        
        let w = image.size.width * CGFloat(newMultiple)
        let h = image.size.height * CGFloat(newMultiple)
        let scale = UIScreen.main.scale
        let rect = CGRect(x: 0, y: 0, width: w, height: h)
        UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
        UIBezierPath(roundedRect: rect, cornerRadius: 0).addClip()
        image.draw(in: rect)
        let tempImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return tempImage
    }
    
    func createImg(multiple:Double) -> UIImage? {
        var newMultiple = multiple
        if multiple == 0 {
            newMultiple = 1
        } else if (fabs(multiple) > 0 && fabs(multiple) < 1) || (fabs(multiple) > 1 && fabs(multiple) < 2) {
            newMultiple = multiple
        } else {
            newMultiple = 1
        }
        
        let w = self.size.width * CGFloat(newMultiple)
        let h = self.size.height * CGFloat(newMultiple)
        let scale = UIScreen.main.scale
        let rect = CGRect(x: 0, y: 0, width: w, height: h)
        UIGraphicsBeginImageContextWithOptions(self.size, false, scale)
        UIBezierPath(roundedRect: rect, cornerRadius: 0).addClip()
        self.draw(in: rect)
        let tempImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return tempImage
    }
    
    
    func imageWithScale(sacle:CGFloat) -> UIImage? {
        let imageHeight = scale * k_s_w / k_s_h
        let currentSize = CGSize(width: imageHeight, height: imageHeight)
        UIGraphicsBeginImageContext(currentSize)
        draw(in: CGRect(x: 0, y: 0, width: imageHeight, height: imageHeight))
        let newImg = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return newImg
    }
    
    class func resetImgSize(sourceImage:UIImage,maxImageLenght:CGFloat,maxSizeKB:CGFloat) -> Data {
        var maxSize = maxSizeKB
        var maxImageSize = maxImageLenght
        
        if (maxSize <= 0.0) {
            maxSize = 1024.0;
        }
        
        if (maxImageSize <= 0.0)  {
            maxImageSize = 1024.0;
        }
        
        //先调整分辨率
        var newSize = CGSize.init(width: sourceImage.size.width, height: sourceImage.size.height)
        let tempHeight = newSize.height / maxImageSize;
        let tempWidth = newSize.width / maxImageSize;
        if (tempWidth > 1.0 && tempWidth > tempHeight) {
            newSize = CGSize.init(width: sourceImage.size.width / tempWidth, height: sourceImage.size.height / tempWidth)
        }
        
        else if (tempHeight > 1.0 && tempWidth < tempHeight){
            newSize = CGSize.init(width: sourceImage.size.width / tempHeight, height: sourceImage.size.height / tempHeight)
        }
        UIGraphicsBeginImageContext(newSize)
        sourceImage.draw(in: CGRect.init(x: 0, y: 0, width: newSize.width, height: newSize.height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        var imageData = newImage!.jpegData(compressionQuality: 1.0)
        var sizeOriginKB : CGFloat = CGFloat((imageData?.count)!) / 1024.0;
        
        //调整大小
        
        var resizeRate = 0.9;
        while (sizeOriginKB > maxSize && resizeRate > 0.1) {
            imageData = newImage!.jpegData(compressionQuality: CGFloat(resizeRate));
            sizeOriginKB = CGFloat((imageData?.count)!) / 1024.0;
            resizeRate -= 0.1;
        }
        return imageData!
    }
    
    
    
    /*!
     *  @brief 使图片压缩后刚好小于指定大小
     *
     *  @param image 当前要压缩的图 maxLength 压缩后的大小
     *
     *  @return 图片对象
     */
    //图片质量压缩到某一范围内，如果后面用到多，可以抽成分类或者工具类,这里压缩递减比二分的运行时间长，二分可以限制下限。
    func compressImageSize(toByte maxLength:Double) -> UIImage {
        //首先判断原图大小是否在要求内，如果满足要求则不进行压缩，over
        var compression:CGFloat = 1
        guard var data = self.jpegData(compressionQuality: compression) else { return self }
        if (Double(data.count) < maxLength) { return self }
        //原图大小超过范围，先进行“压处理”，这里 压缩比 采用二分法进行处理，6次二分后的最小压缩比是0.015625，已经够小了
        var max:CGFloat = 1
        var min:CGFloat = 0
        
        for _ in 0..<6 {
            compression = (max + min) / 2;
            guard let data = self.jpegData(compressionQuality: compression) else { return self }
            if (Double(data.count) < maxLength * 0.9) {
                min = compression;
            } else if (Double(data.count) > maxLength) {
                max = compression;
            } else {
                break;
            }
        }
        //判断“压处理”的结果是否符合要求，符合要求就over
        guard var resultImage = UIImage(data: data) else { return self }
        if (Double(data.count) < maxLength) { return resultImage }
        
        //缩处理，直接用大小的比例作为缩处理的比例进行处理，因为有取整处理，所以一般是需要两次处理
        var lastDataLength:Double = 0
        let length = Double(data.count)
        
        while (length > maxLength && length != lastDataLength) {
            lastDataLength = length
            //获取处理后的尺寸
            let ratio = Double(maxLength) / length
            let width = (Double(resultImage.size.width) * Double(sqrtf(Float(ratio))))
            let height = (Double(resultImage.size.height) * Double(sqrtf(Float(ratio))))
            let size = CGSize(width: width, height: height)
            
            //通过图片上下文进行处理图片
            UIGraphicsBeginImageContext(size);
            resultImage.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
            resultImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
            
            UIGraphicsEndImageContext();
            //获取处理后图片的大小
            data = self.jpegData(compressionQuality: compression) ?? Data()
        }
        
        return resultImage;
    }
}


extension UIImage {
    // 修复图片旋转
    func fixOrientation() -> UIImage {
        if self.imageOrientation == .up {
            return self
        }
        
        var transform = CGAffineTransform.identity
        
        switch self.imageOrientation {
        case .down, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: self.size.height)
            transform = transform.rotated(by: .pi)
            break
            
        case .left, .leftMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.rotated(by: .pi / 2)
            break
            
        case .right, .rightMirrored:
            transform = transform.translatedBy(x: 0, y: self.size.height)
            transform = transform.rotated(by: -.pi / 2)
            break
            
        default:
            break
        }
        
        switch self.imageOrientation {
        case .upMirrored, .downMirrored:
            transform = transform.translatedBy(x: self.size.width, y: 0)
            transform = transform.scaledBy(x: -1, y: 1)
            break
            
        case .leftMirrored, .rightMirrored:
            transform = transform.translatedBy(x: self.size.height, y: 0);
            transform = transform.scaledBy(x: -1, y: 1)
            break
            
        default:
            break
        }
        
        let ctx = CGContext(data: nil, width: Int(self.size.width), height: Int(self.size.height), bitsPerComponent: self.cgImage!.bitsPerComponent, bytesPerRow: 0, space: self.cgImage!.colorSpace!, bitmapInfo: self.cgImage!.bitmapInfo.rawValue)
        ctx?.concatenate(transform)
        
        switch self.imageOrientation {
        case .left, .leftMirrored, .right, .rightMirrored:
            ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.height), height: CGFloat(size.width)))
            break
            
        default:
            ctx?.draw(self.cgImage!, in: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(size.width), height: CGFloat(size.height)))
            break
        }
        
        let cgimg: CGImage = (ctx?.makeImage())!
        let img = UIImage(cgImage: cgimg)
        
        return img
    }
}
